
package com.websocket.echo;

import com.websocket.configurator.HttpSessionConfigurator;
import com.websocket.util.Contains;
import com.websocket.util.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.ThreadContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint(value = "/websocket/echoAnnotation", configurator = HttpSessionConfigurator.class)
public class EchoAnnotation {
    private static Logger logger = LoggerFactory.getLogger(EchoAnnotation.class);

    private static ConcurrentHashMap<String, Session> sessionMap = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(Session session, EndpointConfig config) {
        HttpSession httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
        if (httpSession == null) {
            return;
        }
        logger.info("X-Sessio-Id :{} onOpen", httpSession.getId());

        sessionMap.put(httpSession.getId(), session);
    }

    @OnMessage
    @SuppressWarnings("all")
    public void echoTextMessage(Session session, String msg, boolean last,EndpointConfig config) {
        try {
            logger.info("<-------------------Deal With Text Message---------------------->");
            if (session.isOpen()) {
                logger.info("Session session={}, String msg={}, boolean last={}", session, msg, last);
                session.getBasicRemote().sendText("server reply:" + msg, last);
                if (StringUtils.equals(msg, "simon-img")) {
                    File file = new File("/home/simon/Pictures/img/1.jpg");
                    ByteBuffer byteBuffer = ByteBuffer.wrap(FileUtils.File2byte(file.getAbsolutePath()));
                    session.getBasicRemote().sendBinary(byteBuffer, last);
                }
                if (StringUtils.equals(msg, "reward")) {
                    this.sendToAllCLient("惊喜来了!!!!!");
                }

            }
        } catch (IOException e) {
            try {
                session.close();
            } catch (IOException e1) {
                // Ignore
            }
        }
    }

    @OnMessage
    @SuppressWarnings("all")
    public void echoBinaryMessage(Session session, ByteBuffer buf,
                                  boolean last) {
        try {
            logger.info("<--------------------Deal With Binary Message---------------------->");
            if (session.isOpen()) {
                byte[] bytes = new byte[buf.capacity()];
                for (int i = 0; i < buf.capacity(); i++) {

                    bytes[0] = buf.get(i);
                }

                FileUtils.byte2File(bytes, "/home/simon/Pictures/img", "upload.jpg");
            }
        } catch (Exception e) {
            try {
                session.close();
            } catch (IOException e1) {
                // Ignore
            }
        }
    }

    @OnClose
    public void onClose(CloseReason reason, Session session) {
        logger.info("<-------------------onClose---------------------->");

        sessionMap.remove(session.getId());
        logger.info(reason.toString());
    }

    @OnError
    public void onError(Throwable throwable, Session session) {
        logger.warn("<-------------------onError---------------------->");

        sessionMap.remove(session.getId());
        logger.error(throwable.toString());
    }

    /**
     * 向所有的websocket客户端发送消息
     *
     * @param msg
     */
    public void sendToAllCLient(String msg) {
        Set<Entry<String, Session>> set = sessionMap.entrySet();
        try {
            for (Entry<String, Session> entry : set) {
                entry.getValue().getBasicRemote().sendText(msg, true);
            }
        } catch (IOException e) {
            logger.error(e.getMessage());
            e.printStackTrace();
        }
    }
}
